package com.atguigu.gmall.common.service;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.entity.GmallCorrelationData;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 封装 MQ发消息
 */
@Service
@SuppressWarnings("all")
@Slf4j
public class RabbitService {

    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private RedisTemplate redisTemplate;

    //发消息
    public boolean sendMessage(String exchange, String routingKey, String msg) {

        //封装交换机应答失败之后的返回值
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID 唯一主键
        String correlationDataId = UUID.randomUUID().toString();
        gmallCorrelationData.setId(correlationDataId);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        //路由Key
        gmallCorrelationData.setRoutingKey(routingKey);
        //消息
        gmallCorrelationData.setMessage(msg);

        //使用Redis缓存保存一份  只保存10分钟
        redisTemplate.opsForValue().set(correlationDataId, JSON.toJSONString(gmallCorrelationData), MqConst.OBJECT_TIMEOUT,
                TimeUnit.MINUTES); //队列确认失败时 准备的
        //给定时器任务准备缓存数据  List mq:list = new ArrayList()  mq:list.add()
        //redisTemplate.opsForList().leftPush(MqConst.MQ_KEY_PREFIX,JSON.toJSONString(gmallCorrelationData));
        //发消息
        rabbitTemplate.convertAndSend(exchange, routingKey, msg,gmallCorrelationData);
        return true;
    }

    //发送 延迟消息
    public void sendDelayMessage(String exchange, String routing,String msg, int delayTime) {
        //封装交换机应答失败之后的返回值
        GmallCorrelationData gmallCorrelationData = new GmallCorrelationData();
        //ID 唯一主键
        String correlationDataId = UUID.randomUUID().toString();
        gmallCorrelationData.setId(correlationDataId);
        //交换机
        gmallCorrelationData.setExchange(exchange);
        //路由Key
        gmallCorrelationData.setRoutingKey(routing);
        //消息
        gmallCorrelationData.setMessage(msg);
        //是否是延迟消息
        gmallCorrelationData.setDelay(true);
        //延迟时长
        gmallCorrelationData.setDelayTime(delayTime);
        //使用Redis缓存保存一份  只保存10分钟  队列应答失败的时候会使用到
        redisTemplate.opsForValue().set(correlationDataId, JSON.toJSONString(gmallCorrelationData), MqConst.OBJECT_TIMEOUT,
                TimeUnit.MINUTES);

        //发延迟消息  设置延迟的时间
        rabbitTemplate.convertAndSend(exchange,routing,msg,message -> {
            //设置延迟消息的时间   2*60*60*1000; 2小时  毫秒
            message.getMessageProperties().setDelay(delayTime);
            log.info("取消订单时发消息");
            return message;
        },gmallCorrelationData);//交换机应答失败的时候会使用到
    }
}
